<?php

class Service {
    public $id, $action, $config, $validate=false, $parse=false;
    
    public $validatePresets;
    
    private $components, $states;
    
    public function execute () {
        $this->id = SE::$service['id'];
        $this->action = SE::$service['action'];
        $this->config = SE::$config;
        
        $this->attachComponents();
        $this->init();
        $this->validate();
        $this->parse();
        
        $action = $this->action; $this->$action();
    }
    
    public function init () {}
    
    public function setState ($state, $value) {
        $this->states[$state] = $value;
    }
    
    public function getState ($state) {
        return $this->states[$state];
    }
    
    public function __set ($k,$v) {
        throw new SEException('Set state by Service|Component::setState()!');
    }
    
    public function __get ($state) {
        return $this->states[$state];
    }
    
    public function __call ($method, $args) {
        if(null === $this->components)
            throw new SEException('Call to undefined method '.$this->id.'::'.$method.'()');
        
        if($this->components[$method] instanceof Closure) return $this->components[$method]($args);
        
        foreach($this->components as $comp) {
            if($comp instanceof Component && method_exists($comp, $method))
                return $comp->$method($args);
            else
                throw new SEException('Call to undefined method '.$this->id.'::'.$method.'()');
        }
    }
    
    public function attachClosure ($method, $func) {
        if(null !== $this->components[$alias])
            throw new Seexception('Unable to attahc component '.$alias.', alias already exist!');
        
        $this->components[$method] = $func;
    }
    
    public function attachComponent ($alias, $params) {
        if(null !== $this->components[$alias])
            throw new Seexception('Unable to attahc component '.$alias.', alias already exist!');
        
        $this->components[$alias] = new $params['class']($this, $params, $alias);
    }
    
    private function attachComponents () {
        if(null === $this->config['components']) return false;
        
        foreach($this->config['components'] as $alias=>$params) {
            if(!strstr($params['class'], 'Component')) $params['class'] = $params['class'].'Component';
            $this->attachComponent($alias, $params);
        }
    }
    
    private function validate () {
        if($this->validate === false || !is_array($this->validate)) return false;
        
        foreach($this->validate as $param=>$rule) {
            if(!preg_match($rule, $_GET[$param])) $_GET[$param] = false;
        }
    }
    
    private function parse () { return false;
        if($this->parse === false || !is_array($this->parse)) return false;
        
        foreach($this->parse as $param=>$rule) {
            
        }
    }
}